﻿using Dapper;
using Dapper.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ymatou.ServiceCenter.Domain.IRepositories;
using System.Data.SqlClient;

namespace Ymatou.ServiceCenter.Repository
{
    public abstract class RepositoryBase<TEntity> : IRepositoryBase<TEntity>
        where TEntity : class
    {
        protected string GetConnectionName(string connectionName)
        {
            if (string.IsNullOrWhiteSpace(connectionName))
            {
                IClassMapper<TEntity> classMapper = ClassMapperFactory.GetMapper<TEntity>();
                connectionName = classMapper.ConnectionName;
                if (string.IsNullOrWhiteSpace(connectionName))
                {
                    connectionName = "Default";
                }
            }
            return connectionName;
        }

        #region 根据主键查询单条信息

        public virtual TEntity GetById(string connectionName, string tableName, object id)
        {
            using (IDbContext db = new DbContext(GetConnectionName(connectionName)))
            {
                return db.Get<TEntity>(id, tableName);
            }
        }

        public virtual TEntity GetById(object id)
        {
            return GetById(null, null, id);
        }

        #endregion

        #region 统计查询
        public virtual long Count(string connectionName, string tableName, string condition, DynamicParameters parameters)
        {
            using (IDbContext db = new DbContext(connectionName))
            {
                return db.Count<TEntity>(tableName, condition, parameters);
            }
        }

        public virtual long Count(string condition, DynamicParameters parameters)
        {
            return Count(null, null, condition, parameters);
        }

        public virtual long Count()
        {
            return Count(null, null, null, null);
        }

        #endregion

        #region 保存数据

        public virtual bool Insert(string connectionName, string tableName, TEntity entity)
        {
            using (IDbContext db = new DbContext(GetConnectionName(connectionName)))
            {
                return db.Insert<TEntity>(entity, tableName);
            }
        }

        public virtual bool Insert(TEntity entity)
        {
            return Insert(null, null, entity);
        }

        public virtual bool Insert(IEnumerable<TEntity> entities)
        {
            return Insert(null, null, entities);
        }

        public virtual bool Insert(string connectionName, string tableName, IEnumerable<TEntity> entities)
        {
            using (IDbContext db = new DbContext(GetConnectionName(connectionName)))
            {
                return db.Insert<TEntity>(entities, tableName);
            }
        }

        public virtual bool Update(string connectionName, string tableName, TEntity entity)
        {
            using (IDbContext db = new DbContext(GetConnectionName(connectionName)))
            {
                return db.Update<TEntity>(entity, tableName);
            }
        }

        public virtual bool Update(TEntity entity)
        {
            return Update(null, null, entity);
        }

        public virtual bool Save(string connectionName, string tableName, TEntity entity)
        {
            using (IDbContext db = new DbContext(GetConnectionName(connectionName)))
            {
                return db.Save<TEntity>(entity, tableName);
            }
        }

        public virtual bool Save(TEntity entity)
        {
            return Save(null, null, entity);
        }

        #endregion

        #region 删除数据
        public virtual bool Delete(string connectionName, string tableName, TEntity entity)
        {
            using (IDbContext db = new DbContext(GetConnectionName(connectionName)))
            {
                return db.Delete<TEntity>(entity, tableName);
            }
        }

        public virtual bool Delete(TEntity entity)
        {
            return Delete(null, null, entity);
        }

        public virtual bool Delete(string connectionName, string tableName, object id)
        {
            using (IDbContext db = new DbContext(GetConnectionName(connectionName)))
            {
                return db.Delete<TEntity>(id, tableName);
            }
        }

        public virtual bool Delete(object id)
        {
            return Delete(null, null, id);
        }

        #endregion

        #region 根据多个条件查询数据列表
        public virtual IList<TEntity> GetAll(string connectionName, string tableName)
        {
            return GetList(connectionName, tableName, null, null);
        }

        public virtual IList<TEntity> GetAll()
        {
            return GetAll(null, null);
        }

        public virtual IList<TEntity> Find(string sql, SqlParameter[] parameters)
        {

            var par = new DynamicParameters();

            foreach (var p in parameters)
            {
                par.Add(p.ParameterName, p.Value, dbType: p.DbType);
            }


            using (IDbContext db = new DbContext(GetConnectionName(null)))
            {
                return
                    db.Query<TEntity>(
                        sql, par);

            }
        }

        public virtual IList<TEntity> GetList(string connectionName, string tableName, string condition, DynamicParameters parameters)
        {
            using (IDbContext db = new DbContext(GetConnectionName(connectionName)))
            {
                return db.List<TEntity>(tableName, condition, parameters);
            }
        }

        public virtual IList<TEntity> GetList(string condition, DynamicParameters parameters)
        {
            return GetList(null, null, condition, parameters);
        }

        #endregion

        #region 分页查询
        public virtual PagingInfo<TEntity> PagingQuery(string connectionName, string tableName, string condition, string orderBy, DynamicParameters parameters, int pageSize, int pageIndex)
        {
            PagingInfo<TEntity> pagingInfo = null;
            using (IDbContext db = new DbContext(GetConnectionName(connectionName)))
            {
                PagingResult<TEntity> result = db.Paging<TEntity>(tableName, condition, orderBy, parameters, pageIndex, pageSize);
                if (result != null)
                {
                    pagingInfo = new PagingInfo<TEntity>
                    {
                        List = result.List,
                        TotalPages = result.TotalPages,
                        TotalRecords = result.TotalRecords
                    };
                }
            }
            return pagingInfo;
        }

        public virtual PagingInfo<TEntity> PagingQuery(string condition, string orderBy, DynamicParameters parameters, int pageSize, int pageIndex)
        {
            return PagingQuery(null, null, condition, orderBy, parameters, pageSize, pageIndex);
        }

        #endregion
    }
}
